package com.fr.base.core.image4j.codec.bmp;

import com.fr.base.core.image4j.io.LittleEndianInputStream;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class BMPDecoder
{
  private BufferedImage img;
  private InfoHeader infoHeader;

  public BMPDecoder(InputStream paramInputStream)
    throws IOException
  {
    LittleEndianInputStream localLittleEndianInputStream = new LittleEndianInputStream(paramInputStream);
    byte[] arrayOfByte = new byte[2];
    localLittleEndianInputStream.read(arrayOfByte);
    String str = new String(arrayOfByte, "UTF-8");
    if (!(str.equals("BM")))
      throw new IOException("Invalid signature '" + str + "' for BMP format");
    int i = localLittleEndianInputStream.readIntLE();
    int j = localLittleEndianInputStream.readIntLE();
    int k = localLittleEndianInputStream.readIntLE();
    this.infoHeader = readInfoHeader(localLittleEndianInputStream);
    this.img = read(this.infoHeader, localLittleEndianInputStream);
  }

  private static int getBit(int paramInt1, int paramInt2)
  {
    return (paramInt1 >> 7 - paramInt2 & 0x1);
  }

  private static int getNibble(int paramInt1, int paramInt2)
  {
    return (paramInt1 >> 4 * (1 - paramInt2) & 0xF);
  }

  public InfoHeader getInfoHeader()
  {
    return this.infoHeader;
  }

  public BufferedImage getBufferedImage()
  {
    return this.img;
  }

  private static void getColorTable(ColorEntry[] paramArrayOfColorEntry, byte[] paramArrayOfByte1, byte[] paramArrayOfByte2, byte[] paramArrayOfByte3)
  {
    for (int i = 0; i < paramArrayOfColorEntry.length; ++i)
    {
      paramArrayOfByte1[i] = (byte)paramArrayOfColorEntry[i].bRed;
      paramArrayOfByte2[i] = (byte)paramArrayOfColorEntry[i].bGreen;
      paramArrayOfByte3[i] = (byte)paramArrayOfColorEntry[i].bBlue;
    }
  }

  public static InfoHeader readInfoHeader(LittleEndianInputStream paramLittleEndianInputStream)
    throws IOException
  {
    InfoHeader localInfoHeader = new InfoHeader(paramLittleEndianInputStream);
    return localInfoHeader;
  }

  public static InfoHeader readInfoHeader(LittleEndianInputStream paramLittleEndianInputStream, int paramInt)
    throws IOException
  {
    InfoHeader localInfoHeader = new InfoHeader(paramLittleEndianInputStream, paramInt);
    return localInfoHeader;
  }

  public static BufferedImage read(InfoHeader paramInfoHeader, LittleEndianInputStream paramLittleEndianInputStream)
    throws IOException
  {
    BufferedImage localBufferedImage = null;
    ColorEntry[] arrayOfColorEntry = null;
    if (paramInfoHeader.sBitCount <= 8)
      arrayOfColorEntry = readColorTable(paramInfoHeader, paramLittleEndianInputStream);
    localBufferedImage = read(paramInfoHeader, paramLittleEndianInputStream, arrayOfColorEntry);
    return localBufferedImage;
  }

  public static BufferedImage read(InfoHeader paramInfoHeader, LittleEndianInputStream paramLittleEndianInputStream, ColorEntry[] paramArrayOfColorEntry)
    throws IOException
  {
    BufferedImage localBufferedImage = null;
    if ((paramInfoHeader.sBitCount == 1) && (paramInfoHeader.iCompression == 0))
      localBufferedImage = read1(paramInfoHeader, paramLittleEndianInputStream, paramArrayOfColorEntry);
    else if ((paramInfoHeader.sBitCount == 4) && (paramInfoHeader.iCompression == 0))
      localBufferedImage = read4(paramInfoHeader, paramLittleEndianInputStream, paramArrayOfColorEntry);
    else if ((paramInfoHeader.sBitCount == 8) && (paramInfoHeader.iCompression == 0))
      localBufferedImage = read8(paramInfoHeader, paramLittleEndianInputStream, paramArrayOfColorEntry);
    else if ((paramInfoHeader.sBitCount == 24) && (paramInfoHeader.iCompression == 0))
      localBufferedImage = read24(paramInfoHeader, paramLittleEndianInputStream);
    else if ((paramInfoHeader.sBitCount == 32) && (paramInfoHeader.iCompression == 0))
      localBufferedImage = read32(paramInfoHeader, paramLittleEndianInputStream);
    else
      throw new IOException("Unrecognized bitmap format: bit count=" + paramInfoHeader.sBitCount + ", compression=" + paramInfoHeader.iCompression);
    return localBufferedImage;
  }

  public static ColorEntry[] readColorTable(InfoHeader paramInfoHeader, LittleEndianInputStream paramLittleEndianInputStream)
    throws IOException
  {
    ColorEntry[] arrayOfColorEntry = new ColorEntry[paramInfoHeader.iNumColors];
    for (int i = 0; i < paramInfoHeader.iNumColors; ++i)
    {
      ColorEntry localColorEntry = new ColorEntry(paramLittleEndianInputStream);
      arrayOfColorEntry[i] = localColorEntry;
    }
    return arrayOfColorEntry;
  }

  public static BufferedImage read1(InfoHeader paramInfoHeader, LittleEndianInputStream paramLittleEndianInputStream, ColorEntry[] paramArrayOfColorEntry)
    throws IOException
  {
    byte[] arrayOfByte1 = new byte[paramArrayOfColorEntry.length];
    byte[] arrayOfByte2 = new byte[paramArrayOfColorEntry.length];
    byte[] arrayOfByte3 = new byte[paramArrayOfColorEntry.length];
    getColorTable(paramArrayOfColorEntry, arrayOfByte1, arrayOfByte2, arrayOfByte3);
    IndexColorModel localIndexColorModel = new IndexColorModel(1, 2, arrayOfByte1, arrayOfByte2, arrayOfByte3);
    BufferedImage localBufferedImage = new BufferedImage(paramInfoHeader.iWidth, paramInfoHeader.iHeight, 12, localIndexColorModel);
    WritableRaster localWritableRaster = localBufferedImage.getRaster();
    int i = paramInfoHeader.iWidth;
    int j = i;
    if (j % 32 != 0)
      j = (j / 32 + 1) * 32;
    int k = j - i;
    int l = k / 8;
    int i1 = j / 8;
    int[] arrayOfInt = new int[i1];
    for (int i2 = paramInfoHeader.iHeight - 1; i2 >= 0; --i2)
    {
      for (int i3 = 0; i3 < i1; ++i3)
        arrayOfInt[i3] = paramLittleEndianInputStream.readUnsignedByte();
      for (i3 = 0; i3 < paramInfoHeader.iWidth; ++i3)
      {
        int i4 = i3 / 8;
        int i5 = arrayOfInt[i4];
        int i6 = i3 % 8;
        int i7 = getBit(i5, i6);
        localWritableRaster.setSample(i3, i2, 0, i7);
      }
    }
    return localBufferedImage;
  }

  public static BufferedImage read4(InfoHeader paramInfoHeader, LittleEndianInputStream paramLittleEndianInputStream, ColorEntry[] paramArrayOfColorEntry)
    throws IOException
  {
    byte[] arrayOfByte1 = new byte[paramArrayOfColorEntry.length];
    byte[] arrayOfByte2 = new byte[paramArrayOfColorEntry.length];
    byte[] arrayOfByte3 = new byte[paramArrayOfColorEntry.length];
    getColorTable(paramArrayOfColorEntry, arrayOfByte1, arrayOfByte2, arrayOfByte3);
    IndexColorModel localIndexColorModel = new IndexColorModel(4, paramInfoHeader.iNumColors, arrayOfByte1, arrayOfByte2, arrayOfByte3);
    BufferedImage localBufferedImage = new BufferedImage(paramInfoHeader.iWidth, paramInfoHeader.iHeight, 12, localIndexColorModel);
    WritableRaster localWritableRaster = localBufferedImage.getRaster();
    int i = paramInfoHeader.iWidth * 4;
    if (i % 32 != 0)
      i = (i / 32 + 1) * 32;
    int j = i / 8;
    int[] arrayOfInt = new int[j];
    for (int k = paramInfoHeader.iHeight - 1; k >= 0; --k)
    {
      int i1;
      for (int l = 0; l < j; ++l)
      {
        i1 = paramLittleEndianInputStream.readUnsignedByte();
        arrayOfInt[l] = i1;
      }
      for (l = 0; l < paramInfoHeader.iWidth; ++l)
      {
        i1 = l / 2;
        int i2 = l % 2;
        int i3 = arrayOfInt[i1];
        int i4 = getNibble(i3, i2);
        localWritableRaster.setSample(l, k, 0, i4);
      }
    }
    return localBufferedImage;
  }

  public static BufferedImage read8(InfoHeader paramInfoHeader, LittleEndianInputStream paramLittleEndianInputStream, ColorEntry[] paramArrayOfColorEntry)
    throws IOException
  {
    byte[] arrayOfByte1 = new byte[paramArrayOfColorEntry.length];
    byte[] arrayOfByte2 = new byte[paramArrayOfColorEntry.length];
    byte[] arrayOfByte3 = new byte[paramArrayOfColorEntry.length];
    getColorTable(paramArrayOfColorEntry, arrayOfByte1, arrayOfByte2, arrayOfByte3);
    IndexColorModel localIndexColorModel = new IndexColorModel(8, paramInfoHeader.iNumColors, arrayOfByte1, arrayOfByte2, arrayOfByte3);
    BufferedImage localBufferedImage = new BufferedImage(paramInfoHeader.iWidth, paramInfoHeader.iHeight, 13, localIndexColorModel);
    WritableRaster localWritableRaster = localBufferedImage.getRaster();
    int i = paramInfoHeader.iWidth;
    int j = i;
    if (j % 4 != 0)
      j = (j / 4 + 1) * 4;
    int k = j - i;
    for (int l = paramInfoHeader.iHeight - 1; l >= 0; --l)
    {
      for (int i1 = 0; i1 < paramInfoHeader.iWidth; ++i1)
      {
        int i2 = paramLittleEndianInputStream.readUnsignedByte();
        localWritableRaster.setSample(i1, l, 0, i2);
      }
      paramLittleEndianInputStream.skipBytes(k);
    }
    return localBufferedImage;
  }

  public static BufferedImage read24(InfoHeader paramInfoHeader, LittleEndianInputStream paramLittleEndianInputStream)
    throws IOException
  {
    BufferedImage localBufferedImage = new BufferedImage(paramInfoHeader.iWidth, paramInfoHeader.iHeight, 1);
    WritableRaster localWritableRaster = localBufferedImage.getRaster();
    int i = paramInfoHeader.iWidth * 3;
    int j = i;
    if (j % 4 != 0)
      j = (j / 4 + 1) * 4;
    int k = j - i;
    for (int l = paramInfoHeader.iHeight - 1; l >= 0; --l)
    {
      for (int i1 = 0; i1 < paramInfoHeader.iWidth; ++i1)
      {
        int i2 = paramLittleEndianInputStream.readUnsignedByte();
        int i3 = paramLittleEndianInputStream.readUnsignedByte();
        int i4 = paramLittleEndianInputStream.readUnsignedByte();
        localWritableRaster.setSample(i1, l, 0, i4);
        localWritableRaster.setSample(i1, l, 1, i3);
        localWritableRaster.setSample(i1, l, 2, i2);
      }
      paramLittleEndianInputStream.skipBytes(k);
    }
    return localBufferedImage;
  }

  public static BufferedImage read32(InfoHeader paramInfoHeader, LittleEndianInputStream paramLittleEndianInputStream)
    throws IOException
  {
    BufferedImage localBufferedImage = new BufferedImage(paramInfoHeader.iWidth, paramInfoHeader.iHeight, 2);
    WritableRaster localWritableRaster1 = localBufferedImage.getRaster();
    WritableRaster localWritableRaster2 = localBufferedImage.getAlphaRaster();
    for (int i = paramInfoHeader.iHeight - 1; i >= 0; --i)
      for (int j = 0; j < paramInfoHeader.iWidth; ++j)
      {
        int k = paramLittleEndianInputStream.readUnsignedByte();
        int l = paramLittleEndianInputStream.readUnsignedByte();
        int i1 = paramLittleEndianInputStream.readUnsignedByte();
        int i2 = paramLittleEndianInputStream.readUnsignedByte();
        localWritableRaster1.setSample(j, i, 0, i1);
        localWritableRaster1.setSample(j, i, 1, l);
        localWritableRaster1.setSample(j, i, 2, k);
        localWritableRaster2.setSample(j, i, 0, i2);
      }
    return localBufferedImage;
  }

  public static BufferedImage read(File paramFile)
    throws IOException
  {
    return read(new FileInputStream(paramFile));
  }

  public static BufferedImage read(InputStream paramInputStream)
    throws IOException
  {
    BMPDecoder localBMPDecoder = new BMPDecoder(paramInputStream);
    return localBMPDecoder.getBufferedImage();
  }

  public static BMPImage readExt(File paramFile)
    throws IOException
  {
    return readExt(new FileInputStream(paramFile));
  }

  public static BMPImage readExt(InputStream paramInputStream)
    throws IOException
  {
    BMPDecoder localBMPDecoder = new BMPDecoder(paramInputStream);
    BMPImage localBMPImage = new BMPImage(localBMPDecoder.getBufferedImage(), localBMPDecoder.getInfoHeader());
    return localBMPImage;
  }
}